package com.gitee.apecome.core.remote;

import com.gitee.apecome.core.remote.bean.ApeRpcRequest;
import com.gitee.apecome.core.remote.bean.ApeRpcResponse;
import com.gitee.apecome.core.remote.net.netty.client.Client;
import com.gitee.apecome.core.remote.net.netty.client.NettyConnectClient;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

public class ApeRpcProviderFactory {

    private static volatile ApeRpcProviderFactory instance = new ApeRpcProviderFactory();

    public static ApeRpcProviderFactory newInstance() {
        return instance;
    }

    private Map<String, Object> serviceMap = new ConcurrentHashMap<>();

    public void addService(String serviceKey, Object service) {
        serviceMap.put(serviceKey, service);
    }

    public Object find(String serviceKey) {
        return serviceMap.get(serviceKey);
    }

    public ApeRpcResponse invoke(ApeRpcRequest request) {
        String className = request.getClassName();
        Object o = find(className);
        String errorMsg = "";
        if (Objects.isNull(o)) {
            errorMsg = "provider is null";
        }
        try {
            Method method = o.getClass().getMethod(request.getMethodName(), request.getParameterTypes());
            if (Objects.isNull(method)) {
                errorMsg = "don't get method by methodName";
            }
            Object result = method.invoke(o, request.getParameters());
            return ApeRpcResponse.builder().requestId(request.getRequestId()).errorMsg(errorMsg).result(result).build();
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
            return ApeRpcResponse.builder().requestId(request.getRequestId()).errorMsg(e.getLocalizedMessage()).build();
        }
    }
}
